from PyQt5.QtGui import QImage, QPixmap
from PyQt5.QtWidgets import QFrame, QTabWidget, QSizePolicy\
    , QLCDNumber, QSlider, QLineEdit, QProgressBar
from PyQt5.QtCore import Qt
import sys, os, re

def toBytes(s):
    return bytes(s, 'utf-8')

def toList(t):
    def f(s):
        s = s.split(',')
        arr = []
        for i, j in enumerate(s):
            if type(t) == list:
                arr.append(t[i](j.strip()))
            else:
                arr.append(t(j.strip()))
        return arr
    return f

def cvImg(img):
    if type(img) == str:
        return img
    import cv2
    qimageformat = QImage.Format_Indexed8
    if len(img.shape)==3:
        img = cv2.cvtColor(img, cv2.COLOR_BGR2RGBA)
        qimageformat = QImage.Format_RGBA8888
    q_img = QImage(img, img.shape[1], img.shape[0], img.strides[0], qimageformat)
    q_img = q_img.rgbSwapped()
    return QPixmap.fromImage(q_img)

def cvPathImg(path):
    import cv2
    img = cv2.imread(path)
    return cvImg(img)

def frameShape(style: str):
    style = style.lower()
    d = {
        'none': QFrame.NoFrame,  # QFrame什么都没画
        'box': QFrame.Box,      # QFrame围绕其内容绘制一个框
        'panel': QFrame.Panel,    # QFrame绘制一个面板，使内容显得凸起或凹陷
        'vline': QFrame.VLine,    # QFrame绘制一条无框架的垂直线（用作分隔符）
        'style': QFrame.StyledPanel,  # 绘制一个矩形面板，其外观取决于当前的GUI样式。它可以升起或凹陷。
        'hline': QFrame.HLine
    }
    if style not in d.keys():
        style = 'none'
    return d[style]

def frameShadow(shadow: str):
    shadow = shadow.lower()
    d = {
        'plain': QFrame.Plain,  # 框架和内容与周围环境呈现水平;（没有任何3D效果）
        'raised': QFrame.Raised, # 框架和内容出现; 使用当前颜色组的浅色和深色绘制3D凸起线
        'sunken': QFrame.Sunken, # 框架和内容出现凹陷; 使用当前颜色组的浅色和深色绘制3D凹陷线
    }
    if shadow not in d.keys():
        shadow = 'plain'
    return d[shadow]

def alignment(pos):
    pos = re.sub(r'\s+', '', pos)
    pos = pos.lower().split(',')
    d = {
        'center': Qt.AlignCenter,
        'hcenter': Qt.AlignHCenter,
        'vcenter': Qt.AlignVCenter,
        'bottom': Qt.AlignBottom,
        'top': Qt.AlignTop,
        'right': Qt.AlignRight,
        'left': Qt.AlignLeft
    }
    if len(pos) == 1 and pos[0] in d.keys():
        return d[pos[0]]
    elif len(pos) == 2 and pos[0] in d.keys() and pos[1] in d.keys():
        return d[pos[0]] | d[pos[1]]
    else:
        return d['center']

def sizePolicy(policy):
    arr = [s.strip() for s in policy.lower().split(',')]
    d = {
        'fixed': QSizePolicy.Fixed,
        'min': QSizePolicy.Minimum,
        'max': QSizePolicy.Maximum,
        'preferred': QSizePolicy.Preferred,
        'expanding': QSizePolicy.Expanding,
        'min_expanding': QSizePolicy.MinimumExpanding,
        'none': QSizePolicy.Ignored
    }
    l = []
    for i in range(2):
        if len(arr) >= i + 1:
            l.append(d.get(arr[i], QSizePolicy.Ignored))
        else:
            l.append(QSizePolicy.Ignored)
    return l

def tabPosition(pos: str):
    pos = pos.lower()
    d = {
        'north': QTabWidget.North,
        'south': QTabWidget.South,
        'west': QTabWidget.West,
        'east': QTabWidget.East
    }
    return d[pos]

def readFile(path):
    base_path = sys.path[0]
    path = path.split(',')
    qss = ''
    for p in path:
        p = os.path.join(base_path, p.strip())
        with open(p, 'r') as fp:
            qss += fp.read()
    return qss

def cursorType(s):
    s = s.lower()
    d = {
        'arrow': Qt.CursorShape.ArrowCursor,
        'up_arrow': Qt.CursorShape.UpArrowCursor,
        'cross': Qt.CursorShape.CrossCursor,
        'wait': Qt.CursorShape.WaitCursor,
        'ibeam': Qt.CursorShape.IBeamCursor,
        'size_v': Qt.CursorShape.SizeVerCursor,
        'size_h': Qt.CursorShape.SizeHorCursor,
        'size_b_d': Qt.CursorShape.SizeBDiagCursor,
        'size_f_d': Qt.CursorShape.SizeFDiagCursor,
        'size_all': Qt.CursorShape.SizeAllCursor,
        'blank': Qt.CursorShape.BlankCursor,
        'split_h': Qt.CursorShape.SplitHCursor,
        'split_v': Qt.CursorShape.SplitVCursor,
        'point': Qt.CursorShape.PointingHandCursor,
        'forbidden': Qt.CursorShape.ForbiddenCursor,
        'open_hand': Qt.CursorShape.OpenHandCursor,
        'closed_hand': Qt.CursorShape.ClosedHandCursor,
        'what_this': Qt.CursorShape.WhatsThisCursor,
        'busy': Qt.CursorShape.BusyCursor,
        'last': Qt.CursorShape.LastCursor,
        'bitmap': Qt.CursorShape.BitmapCursor,
        'custom': Qt.CursorShape.CustomCursor,
        'drag_copy': Qt.CursorShape.DragCopyCursor,
        'drag_move': Qt.CursorShape.DragMoveCursor,
        'drag_link': Qt.CursorShape.DragLinkCursor
    }
    return d[s]

def lcdMode(s):
    s = s.lower()
    d = {
        'bin': QLCDNumber.Bin,
        'oct': QLCDNumber.Oct,
        'dec': QLCDNumber.Dec,
        'hex': QLCDNumber.Hex
    }
    return d[s]

def lcdStyle(s):
    s = s.lower()
    d = {
        'outline': QLCDNumber.Outline,
        'filled': QLCDNumber.Filled,
        'flat': QLCDNumber.Flat
    }
    return d[s]

def sliderPos(pos: str):
    pos = pos.lower()
    tp = QSlider
    d = {
        'left': tp.TicksLeft,
        'right': tp.TicksRight,
        'no': tp.NoTicks,
        'above': tp.TicksAbove,
        'below': tp.TicksBelow,
        'both': tp.TicksBothSides
    }
    return d[pos]

def dir(pos: str):
    pos = pos.lower()
    d = {
        'h': Qt.Horizontal,
        'v': Qt.Vertical
    }
    return d[pos]

def echoMode(mode: str):
    mode = mode.lower()
    d = {
        'normal': QLineEdit.Normal,
        'no_echo': QLineEdit.NoEcho,
        'password': QLineEdit.Password,
        'password_echo': QLineEdit.PasswordEchoOnEdit
    }
    return d[mode]

def progressTextDir(dir: str):
    dir = dir.lower()
    d = {
        'top2bottom': QProgressBar.TopToBottom,
        'bottom2top': QProgressBar.BottomToTop
    }
    return d[dir]